package zhao.tx.eecs.Service;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.andware.volley.Request;
import com.andware.volley.VolleyError;
import com.google.gson.Gson;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
import org.json.JSONArray;
import org.json.JSONException;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import zhao.tx.eecs.JsonModel.LocationModel;
import zhao.tx.eecs.JsonModel.MessageModel;
import zhao.tx.eecs.JsonModel.ParamsModel;
import zhao.tx.eecs.MyConstants;
import zhao.tx.eecs.Tools.ParamsFileDeal;
import zhao.tx.eecs.Tools.SharedPreferencesHelper;
import zhao.tx.eecs.Tools.VolleyBase;
import zhao.tx.eecs.Tools.VolleyCookieBase;

public class LocationService extends Service implements LocationListener {

    private IBinder binder = new LocalBinder ();

    private MyThread myThread = new MyThread ();

    private JSONArray jsonArray = new JSONArray (  ) ;
    ExecutorService mThreadPool = Executors.newSingleThreadExecutor ();

    private LocationManager locationManager;
    private List< LocationModel > locationList = new ArrayList< LocationModel > ();


    private ParamsModel paramsModel;

    private Request request;

    private Context context;

    private long maxAge = 0L;


    private static List<gpsInterface> eventList = new ArrayList< gpsInterface > (  );

    public static void addEvent ( gpsInterface gpsInterface ) {
        eventList.add ( gpsInterface );
    }

    public static void removeEvent ( gpsInterface gpsInterface ) {
        eventList.remove ( gpsInterface );
    }


    public interface gpsInterface {
        public void openGps ();
    }

    public LocationService () {
    }

    @Override
    public IBinder onBind ( Intent intent ) {
        return binder;
    }

    @Override
    public void onCreate () {
        super.onCreate ();
        context = this;

        doWatchDog (context);
        locationManager = ( LocationManager ) this
                .getSystemService ( Context.LOCATION_SERVICE );


    }

    private static void doWatchDog ( Context context ) {
        Intent intent = new Intent ( context, WatchdogService.class );
        context.startService ( intent );
    }

    @Override
    public void onStart ( Intent intent, int startId ) {
        super.onStart ( intent, startId );

        if ( ! isGPSEnable () ) {
            for (int i = 0; i < eventList.size(); i++)
                ((gpsInterface) eventList.get(i)).openGps ();
        }

        Thread thread = new Thread ( new Runnable () {
            @Override
            public void run () {
                if ( ParamsFileDeal.isExists ( context ) ) {
                    paramsModel = ParamsFileDeal.getFile ( context );
                    request = VolleyCookieBase.volleyGet ( MyConstants.PARAMS, ParamsModel.class, paramsModel.getUpdated_at (), MyConstants.MyCookie, getParamsHandler );
                } else {
                    VolleyCookieBase.volleyGet ( MyConstants.PARAMS, ParamsModel.class, MyConstants.MyCookie, getParamsHandler );
                }


                if ( SharedPreferencesHelper.isMaxAgeExists ( context ) ) {
                    maxAge = SharedPreferencesHelper.getMaxAge ( context );
                }

                while ( !isGPSEnable () ) {
                    try {
                        Thread.sleep ( 1000 );
                    } catch ( InterruptedException e ) {
                        e.printStackTrace ();
                    }
                }

                if ( isGPSEnable () ) {
                    handler.sendEmptyMessage ( 0 );
                }
            }
        } );
        thread.start ();

    }

    Handler handler = new Handler (  ) {

        @Override
        public void handleMessage ( Message msg ) {
            super.handleMessage ( msg );
            locationManager.requestLocationUpdates ( LocationManager.GPS_PROVIDER, 1000, 0, LocationService.this );

        }
    };


    private boolean isGPSEnable () {
        /* 用Setting.System来读取也可以，只是这是更旧的用法
        String str = Settings.System.getString(getContentResolver(),
                Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        */
        return locationManager.isProviderEnabled ( LocationManager.GPS_PROVIDER );
    }



    //定义内容类继承Binder
    public class LocalBinder extends Binder {
        //返回本地服务
        LocationService getService () {
            return LocationService.this;
        }
    }

    private class MyThread extends Thread implements Runnable {
        @Override
        public boolean isInterrupted () {
            return isInterrupted;
        }

        public void setInterrupted ( boolean isInterrupted ) {
            this.isInterrupted = isInterrupted;
        }

        private boolean isInterrupted = false;

        @Override
        public void run () {
            super.run ();
            while ( ! isInterrupted ) {
                try {
                    Thread.sleep ( paramsModel.getGps_upload_interval () * 1000 );
//                    Thread.sleep ( 40 * 1000 );//test
                } catch ( InterruptedException e ) {
                    e.printStackTrace ();
                }
                try {

                    int j = 0;
                    for ( int i = 0 ; i < paramsModel.getGps_max_per_upload () ; i++ ) {
                        if ( j < locationList.size () ) {

                            JSONArray subJsonArray = new JSONArray (  );
                            subJsonArray.put ( locationList.get ( j ).getLongitude () );
                            subJsonArray.put ( locationList.get ( j ).getLatitude () );
                            subJsonArray.put ( locationList.get ( j ).getAltitude () );
                            subJsonArray.put ( locationList.get ( j ).getAccuracy () );
                            subJsonArray.put ( locationList.get ( j ).getTime () );
                            jsonArray.put ( subJsonArray );
                            j++;
                        }

                    }

                } catch ( JSONException e ) {
                    e.printStackTrace ();
                }
                if ( jsonArray.length () != 0 ) {
                    VolleyCookieBase.volleyPostBaseNull ( MyConstants.POSITION, jsonArray.toString (), MyConstants.MyCookie, uploadLocationHandler );
                }
            }
        }
    }


    Handler getParamsHandler = new Handler () {

        @Override
        public void handleMessage ( Message msg ) {
            super.handleMessage ( msg );
            switch ( msg.what ) {
                case VolleyBase.SUCCESS:
                    paramsModel = ( ParamsModel ) msg.obj;
                    ParamsFileDeal.saveFile ( context, paramsModel );
                    break;
                case VolleyBase.FAILD:

                    break;
            }
        }
    };

    Handler uploadLocationHandler = new Handler () {

        @Override
        public void handleMessage ( Message msg ) {
            super.handleMessage ( msg );
            switch ( msg.what ) {
                case VolleyBase.SUCCESS:
                    locationList.clear ();
                    jsonArray = new JSONArray ();
                    Log.i ( "uploadLocation", "上传成功!" );
                    break;
                case VolleyBase.FAILD:
                    locationList.clear ();
                    jsonArray = new JSONArray ();
                    Log.i ( "uploadLocation", "上传失败!" );
                    if ( msg.obj instanceof VolleyError ) {
                        VolleyError error = ( VolleyError ) msg.obj;
                        if ( error.networkResponse != null ) {
                            if ( error.networkResponse.data != null ) {
                                String faileValue = new String ( error.networkResponse.data );
                                Gson gson = new Gson ();
                                MessageModel message = gson.fromJson ( faileValue, MessageModel.class );
                                Log.i ( "FailedValue", "value:" + message.getMsg () );
                                Toast.makeText ( context, message.getMsg (), Toast.LENGTH_SHORT ).show ();
                            }
                        }
                    }
                    break;
            }
        }
    };




    @Override
    public void onLocationChanged ( final Location location ) {
        Log.i ( "getLocation", "addLocation" );
        mThreadPool.execute ( new Runnable () {
            @Override
            public void run () {
                if ( paramsModel != null ) {
                    try {
                        Thread.sleep ( paramsModel.getGps_acquisition_interval () * 1000 );
//                        Thread.sleep ( 10 * 1000 );//test

                        LocationModel locationModel = new LocationModel ();
                        locationModel.setAltitude ( location.getAltitude () );
                        locationModel.setAccuracy ( location.getAccuracy () );
                        locationModel.setLongitude ( location.getLongitude () );
                        locationModel.setLatitude ( location.getLatitude () );
                        DateTime dateTime;
                        if ( maxAge != 0L ) {
                            long time = System.currentTimeMillis () + ( maxAge * 1000 );
                            Date date = new Date ( time );

                            dateTime = new DateTime ( date ).withZone ( DateTimeZone.UTC );

                        } else {
                            dateTime = new DateTime ( DateTimeZone.UTC );
                        }
                        String time = dateTime.toString ( ISODateTimeFormat.dateTime () );
                        Log.i ( "getLocation", "addTime:" + time );
                        locationModel.setTime ( time );
                        locationList.add ( locationModel );
                        if ( ! myThread.isAlive () ) {
                            myThread.start ();
                        }

                    } catch ( InterruptedException e ) {
                        e.printStackTrace ();
                    }
                }
            }
        } );
    }

    @Override
    public void onStatusChanged ( String provider, int status, Bundle extras ) {

    }

    @Override
    public void onProviderEnabled ( String provider ) {

    }

    @Override
    public void onProviderDisabled ( String provider ) {

    }

    public static boolean isWorked ( Context context ) {
        ActivityManager myManager = ( ActivityManager ) context.getSystemService ( Context.ACTIVITY_SERVICE );
        ArrayList< RunningServiceInfo > runningService = ( ArrayList< RunningServiceInfo > ) myManager.getRunningServices ( 30 );
        for ( int i = 0 ; i < runningService.size () ; i++ ) {
            if ( runningService.get ( i ).service.getClassName ().toString ().equals ( "zhao.tx.eecs.Service.LocationService" ) ) {
                return true;
            }
        }
        return false;
    }

}
